﻿using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections;
using System.Windows.Forms;

enum Mode{
	PERSPECTIVE = 0,
	PERSPECTIVE_NO_ANIMATION = 1,
	FOREGROUND = 2,
	BACKGROUND = 3
}

enum State{
	NULL,
	NORMAL,
	SHOW_BG_ANIMATION,
	HIDE_BG_ANIMATION,
	SHOWING_BG,
	CONFIG
}

public class Manager : MonoBehaviour {

	[Header("Basic")]
	public GameObject Foreground;
	public GameObject Background;
	public GameObject Mask;

	[Header("Config")]
	public GameObject ConfigPanel;
	public Text ForegroundPath;
	public Text BackgroundPath;
	public Sprite DefaultForeground;
	public Sprite DefaultBackground;

	public Text sbText;
	public Scrollbar sb;
	public GameObject sbHandle;

	public Text ModeLabel;

	public Text EggLabel;

	[Header("Debug")]
	public Text DebugInfo;

	private static float MASK_DEFAULT_SIZE = 300f;
	private static float MASK_CONFIG_MAX_SIZE = 1000f;
	private static float MASK_MAX_SIZE = 5000f;
	private static float MASK_ANIMATION_LARGEN_OFFSET = 30f;
	//private static float MASK_SCROLLWHEEL_LARGEN_OFFSET = 10f;

	//private static Vector2 CANVAS_SIZE = new Vector2 (1920f, 1080f);

	private float _maskCurrentSize;

	private Mode _mode;

	private State _state = State.NORMAL;
	private State _stateAfterConfig = State.NULL;

	void Start () {
		
		//PlayerPrefs.DeleteAll ();

		// Create Default Config if NOT exist
		if(PlayerPrefs.GetString("ForegroundPath") == null){
			PlayerPrefs.SetString ("ForegroundPath", "Default");
		}
		if(PlayerPrefs.GetString("BackgroundPath") == null){
			PlayerPrefs.SetString ("BackgroundPath", "Default");
		}
		if (PlayerPrefs.GetInt ("Mode",-1) == -1) {
			PlayerPrefs.SetInt ("Mode", (int)Mode.PERSPECTIVE);
		}
		if (PlayerPrefs.GetFloat ("MaskSize",-1f) == -1f) {
			PlayerPrefs.SetFloat ("MaskSize", MASK_DEFAULT_SIZE);
		}

		// Load Config
		if (PlayerPrefs.GetString ("ForegroundPath") == "Default") {
			//Foreground.GetComponent<Image> ().sprite = DefaultForeground;
			setPicToDefault (true);
		} else {
			StartCoroutine (setLocalPic(PlayerPrefs.GetString ("ForegroundPath"), true));
		}

		if (PlayerPrefs.GetString ("BackgroundPath") == "Default") {
			//Background.GetComponent<Image> ().sprite = DefaultBackground;
			setPicToDefault (false);
		} else {
			StartCoroutine (setLocalPic(PlayerPrefs.GetString ("BackgroundPath"), false));
		}

		_mode = (Mode)(PlayerPrefs.GetInt ("Mode"));
		setMode (_mode);

		_maskCurrentSize = PlayerPrefs.GetFloat ("MaskSize");
		Mask.GetComponent<RectTransform> ().sizeDelta = new Vector2 (_maskCurrentSize, _maskCurrentSize);
		sb.value = _maskCurrentSize / MASK_CONFIG_MAX_SIZE;
	}

	void Update () {

		// Just for debug, WallPaper Engine CANNOT receive keyboard input
		if (Input.GetKeyDown (KeyCode.H)) {
			DebugInfo.gameObject.SetActive (false);
		}else if(Input.GetKeyDown (KeyCode.S)){
			DebugInfo.gameObject.SetActive (true);
		}

		if (_mode == Mode.PERSPECTIVE || _mode == Mode.PERSPECTIVE_NO_ANIMATION) {
			
			switch (_state) {
			case State.NORMAL:
				/* Legacy, WallPaper Engine CANNOT receive keyboard input
			if (Input.GetKeyDown (KeyCode.Mouse0)) {
				state = State.SHOW_BG_ANIMATION;
				StartCoroutine (BgAnimation(true));
			} else if(Input.GetAxis("Mouse ScrollWheel") < 0) {
				if (Mask.GetComponent<RectTransform> ().sizeDelta.x > 0) {
					Mask.GetComponent<RectTransform> ().sizeDelta -= new Vector2 (MASK_SCROLLWHEEL_LARGEN_OFFSET, MASK_SCROLLWHEEL_LARGEN_OFFSET);
				}
			} else if(Input.GetAxis("Mouse ScrollWheel") > 0) {
				if (Mask.GetComponent<RectTransform> ().sizeDelta.x < MASK_MAX_SIZE) {
					Mask.GetComponent<RectTransform> ().sizeDelta += new Vector2 (MASK_SCROLLWHEEL_LARGEN_OFFSET, MASK_SCROLLWHEEL_LARGEN_OFFSET);
				}
			} else {
				Mask.GetComponent<RectTransform> ().anchoredPosition = getCursorPosition(Input.mousePosition);
			}
			*/
				Mask.GetComponent<RectTransform> ().anchoredPosition = getCursorPosition (Input.mousePosition);
				break;

			case State.SHOW_BG_ANIMATION:
				break;

			case State.HIDE_BG_ANIMATION:
				Mask.GetComponent<RectTransform> ().anchoredPosition = getCursorPosition (Input.mousePosition);
				break;

			case State.SHOWING_BG:
				/*
			if (Input.GetKeyDown (KeyCode.Mouse0)) {
				_state = State.HIDE_BG_ANIMATION;
				StartCoroutine (BgAnimation(false));
			}
			*/
				break;
			}

			// Set Config Panel
			sb.enabled = (_stateAfterConfig == State.NORMAL);
			if (sb.enabled) {
				sbText.text = "透视区域半径"; 
				sbHandle.SetActive (true);
			} else {
				sbText.text = "透视区域半径（当前不可用）"; 
				sbHandle.SetActive (false);
			}

		} else {

			// Set Config Panel
			sb.enabled = false;
			sbText.text = "透视区域半径（当前不可用）";
			sbHandle.SetActive (false);
		}

		Background.GetComponent<RectTransform> ().position = Vector3.zero;

		// Debug
		showDebugInfo ();
	}

	IEnumerator BgAnimation(bool isShow){
		
		if (isShow) {
			while (Mask.GetComponent<RectTransform> ().sizeDelta.x < MASK_MAX_SIZE) {

				Mask.GetComponent<RectTransform> ().sizeDelta += new Vector2 (MASK_ANIMATION_LARGEN_OFFSET, MASK_ANIMATION_LARGEN_OFFSET);
				yield return new WaitForFixedUpdate ();
			}

			if (_state == State.CONFIG) {
				_stateAfterConfig = State.SHOWING_BG;
			} else {
				_state = State.SHOWING_BG;
			}
		} else {
			while (Mask.GetComponent<RectTransform> ().sizeDelta.x > _maskCurrentSize) {

				Mask.GetComponent<RectTransform> ().sizeDelta -= new Vector2 (MASK_ANIMATION_LARGEN_OFFSET, MASK_ANIMATION_LARGEN_OFFSET);
				yield return new WaitForFixedUpdate ();
			}

			if (_state == State.CONFIG) {
				_stateAfterConfig = State.NORMAL;
			} else {
				_state = State.NORMAL;
			}
		}
	}

	private Vector2 getCursorPosition(Vector3 mousePos){

		Vector2 v = Vector2.zero;

		v.x = mousePos.x * 1920f/UnityEngine.Screen.width;
		v.y = mousePos.y * 1080f/UnityEngine.Screen.height;

		return v;
	}

	#region Change Pic

	IEnumerator setLocalPic(string path, bool isForeground){

		WWW www = new WWW ("file://" + path);
		yield return www;   

		if (www != null && string.IsNullOrEmpty (www.error)) {
			Texture2D texture = www.texture;
			Sprite sprite = Sprite.Create (texture, new Rect (0, 0, texture.width, texture.height), new Vector2 (0.5f, 0.5f));

			if (isForeground) {
				ForegroundPath.text = path;
				Foreground.GetComponent<Image> ().sprite = sprite;
				PlayerPrefs.SetString ("ForegroundPath", path);
			} else {
				BackgroundPath.text = path;
				Background.GetComponent<Image> ().sprite = sprite;
				PlayerPrefs.SetString ("BackgroundPath", path);
			}
		} else {
			setPicToDefault (isForeground);
		}
	}

	public void setPicToDefault(bool isForeground)
	{
		if (isForeground) {
			ForegroundPath.text = "默认图片";
			Foreground.GetComponent<Image> ().sprite = DefaultForeground;
			PlayerPrefs.SetString ("ForegroundPath","Default");
		} else {
			BackgroundPath.text = "默认图片";
			Background.GetComponent<Image> ().sprite = DefaultBackground;
			PlayerPrefs.SetString ("BackgroundPath","Default");
		}
	}

	#endregion

	#region UI Event / Config Panel

	public void OnSizeScrollBarValueChanged(Scrollbar sb){
		
		float newMaskSize = sb.value * MASK_CONFIG_MAX_SIZE;

		Mask.GetComponent<RectTransform> ().sizeDelta = new Vector2 (newMaskSize, newMaskSize);
		_maskCurrentSize = newMaskSize;

		PlayerPrefs.SetFloat ("MaskSize",_maskCurrentSize);
	}

	public void OnScreenBtnClick(){

		if(_mode != Mode.PERSPECTIVE && _mode != Mode.PERSPECTIVE_NO_ANIMATION){
			return;
		}

		if(_mode == Mode.PERSPECTIVE_NO_ANIMATION && _state != State.SHOWING_BG){
			return;
		}

		switch (_state) {
		case State.NORMAL:
			_state = State.SHOW_BG_ANIMATION;
			StartCoroutine (BgAnimation (true));
			break;

		case State.SHOWING_BG:
			_state = State.HIDE_BG_ANIMATION;
			StartCoroutine (BgAnimation(false));
			break;
		}

	}

	public void OnConfigBtnClick(){

		//Debug.Log ("[Manager] OnConfigBtnClick");

		if (_state != State.CONFIG) {
			ConfigPanel.SetActive (true);

			//sb.enabled = (_state == State.NORMAL);

			_stateAfterConfig = _state;
			_state = State.CONFIG;
		} else {
			ConfigPanel.SetActive (false);
			if (_stateAfterConfig != State.NULL) {
				_state = _stateAfterConfig;
			} else {
				Debug.LogError ("[Manager] State switch ERROR");
			}
		}
	}

	public void OnBrowsePicBtnClick(bool isForeground)
	{
		OpenFileDialog ofd = new OpenFileDialog();
		if (isForeground) {
			ofd.Title = "选择前景图片";
		} else {
			ofd.Title = "选择背景图片";
		}
		ofd.InitialDirectory = Environment.SpecialFolder.MyComputer.ToString();
		ofd.Filter = "png files (*.png)|*.png|jpg files (*.jpg)|*.jpg|All files (*.*)|*.*";
		DialogResult dr = ofd.ShowDialog ();

		if (dr == DialogResult.OK) {

			string path = ofd.FileName;
			StartCoroutine (setLocalPic(path, isForeground));
		}
	}

	public void OnDefaultPicBtnClick(bool isForeground)
	{
		setPicToDefault (isForeground);
	}

	public void Egg(Scrollbar sb){
		if (sb.value == 1) {
			EggLabel.text = "年轻人别手贱啊";
			sb.gameObject.GetComponent<Animator> ().enabled = true;
			Destroy (sb.gameObject, 3f);
		}
	}

	public void OnModeBtnClick(int mode)
	{
		_mode = (Mode)mode;

		PlayerPrefs.SetInt ("Mode", mode);

		setMode (_mode);
	}

	private void setMode(Mode mode){
		
		switch (mode) {
		case Mode.PERSPECTIVE:
			Mask.SetActive (true);
			Mask.GetComponent<Mask> ().enabled = true;
			ModeLabel.text = "模式选择（透视模式）";
			break;

		case Mode.PERSPECTIVE_NO_ANIMATION:
			Mask.SetActive(true);
			Mask.GetComponent<Mask> ().enabled = true;
			ModeLabel.text = "模式选择（无动画模式）";
			break;

		case Mode.FOREGROUND:
			Mask.SetActive(false);
			ModeLabel.text = "模式选择（前景模式）";
			break;

		case Mode.BACKGROUND:
			Mask.SetActive(true);
			Mask.GetComponent<Mask> ().enabled = false;
			ModeLabel.text = "模式选择（背景模式）";
			break;
		}
	}

	#endregion

	#region Debug

	private void showDebugInfo(){

		DebugInfo.text = 
			"Resolution: " + UnityEngine.Screen.width + " x " + UnityEngine.Screen.height + '\n' +
			"MaskCurrentSize: " + _maskCurrentSize + '\n' +
			"MouseOriginPosition: " + Input.mousePosition + '\n' +
			"MouseFixedPosition: " + getCursorPosition(Input.mousePosition) + '\n' +
			"MaskRestAnchoredPosition: " + Mask.GetComponent<RectTransform> ().anchoredPosition + '\n'+
			"Mode: " + _mode.ToString() + '\n'+
			"State: " + _state.ToString() + '\n'+
			"StateAfterConfig: " + _stateAfterConfig.ToString() + '\n';
	}

	#endregion
}
